/*
 * This file is part of din.
 *
 * din is copyright (c) 2006 - 2012 S Jagannathan <jag@dinisnoise.org>
 * For more information, please visit http://dinisnoise.org
 *
 * din is free software: you can redistribute it and/or modify
 * it under the terms of the GNU General Public License as published by
 * the Free Software Foundation, either version 2 of the License, or
 * (at your option) any later version.
 *
 * din is distributed in the hope that it will be useful, but WITHOUT
 * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
 * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
 * for more details.
 *
 * You should have received a copy of the GNU General Public License along
 * with din.  If not, see <http://www.gnu.org/licenses/>.
 *
*/
#include "curve_library.h"
#include "curve_editor.h"
#include "console.h"
#include "utils.h"
#include "ansi_color_codes.h"
#include "solver.h"

#include <algorithm>

using namespace std;

extern console cons;

void curve_library::load (const string& fname) {

  ifstream inf (fname.c_str(), ios::in);

  if (inf) {

    string ignore;
    int ncurves; inf >> ignore >> ncurves;
    for (int i = 0; i < ncurves; ++i) {
      multi_curve m;
      m.load (inf);
      curves.push_back (m);
      if (has_sustain) {
				float sus; inf >> ignore >> sus;
				sustains.push_back (sus);
			}
    }
    cout << PASS << "<<< loaded " << ncurves << " curves from: " << fname << " >>>" << ENDL;

  }
  cur = 0;
}


curve_library::curve_library (const string& fname, int hs) {
  filename = fname;
	cur = 0;
	has_sustain = hs;
  load (filename);
}

curve_library::~curve_library () {
  save ();
}

void curve_library::add (const multi_curve& m) {
  curves.push_back (m);
  cons << "added curve " << num_curves() - 1 << eol;
}

void curve_library::del () {
  curves.erase (curves.begin() + cur);
  if (has_sustain) sustains.erase (sustains.begin() + cur);  
  clamp<int> (0, cur, curves.size () - 1);
  cons << "erased curve " << cur << eol;
}

void curve_library::replace (const multi_curve& m) {
  curves[cur] = m;
  cons << "replaced curve " << cur << eol;
}

void curve_library::insert (const multi_curve& m) {
  curves.insert (curves.begin() + cur, m);
  cons << "inserted curve " << cur << eol;
}

const multi_curve& curve_library::prev () {
  if (--cur < 0) cur = curves.size() - 1;
  cons << "loaded " << curves[cur].name << " [" << cur + 1 << '/' << curves.size() << "]" << eol;
  return curves[cur];
}

const multi_curve& curve_library::next () {
  if (++cur >= (int)curves.size()) cur = 0;
  cons << "loaded " << curves[cur].name << " [" << cur + 1 << '/' << curves.size() << "]" << eol;
  return curves[cur];
}

void curve_library::move (int i) {

  multi_curve& from = curves [cur];

  cons << "move from: " << cur;

  int j = cur + i;
  int last = curves.size() - 1;
  if (j < 0) j = 0; else if (j > last) j = last;

  multi_curve to = curves[j];
  curves[j] = from;
  from = to;
  cur = j;
	
	if (has_sustain) swap (sustains[cur], sustains[j]);
	
  cons << " to: " << cur << eol;

}

void curve_library::save () {
  ofstream outf (filename.c_str(), ios::out);
  if (outf) {
    outf << "num_curves " << num_curves () << endl;
    for (int i = 0, j = num_curves(); i < j; ++i) {
      curves[i].save (outf);
      if (has_sustain) outf << "sustain " << sustains[i] << eol;
    }
  }
}
